package service

import (
	"fmt"
	ClickHouse "gin/database"
	"gin/model"
	"gin/types"
	"github.com/gin-gonic/gin"
	"strconv"
	"strings"
	"time"
)

type Project struct {
}

type ProjectIpData struct {
	Id            int64   `json:"id" gorm:"column:id"`
	Name          string  `json:"name" gorm:"column:name"`
	ProjectStatus int64   `json:"project_status" gorm:"column:project_status"`
	Status        string  `json:"status" gorm:"-"`
	Percent       float64 `json:"percent" gorm:"-"`
	Code          string  `json:"code" gorm:"column:code"`
	Type          string  `json:"type" gorm:"column:type"`
	Created       int64   `json:"created" gorm:"column:created"`
}

type ProjectNameMapData struct {
	Id   int64  `json:"id" gorm:"column:id"`
	Name string `json:"name" gorm:"column:name"`
}

type GetAllSpendReq struct {
	Date uint64 `json:"date"`
	User uint64 `json:"user"`
}

// 获取指定项目的进度
// 已经完成的任务数量 / 总任务数据
func getProjectTaskPercent(projectId int64) (percent float64, err error) {
	// 已经完成任务状态
	var StatusService Status
	corresponds := []string{"done", "blocked"}
	ipStatusIds, _ := StatusService.GetStatusIdsByCorrespond(corresponds)

	// 获取已经完成任务数量
	taskDb := ClickHouse.DB.Model(&model.Task{})

	var allTaskTotal int64
	taskDb.Where("project_id = ?", projectId).Count(&allTaskTotal)

	var doneTaskTotal int64
	err = taskDb.Where("simpleJSONExtractString(`task`.`json`, 'task_status') IN ?", ipStatusIds).Count(&doneTaskTotal).Error
	if doneTaskTotal > 0 {
		percent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", float64(doneTaskTotal)/float64(allTaskTotal)), 64)
	}
	return
}

// 获取进行中的项目列表
// correspond = in_progress，daily，feedback 这三种类型的状态为进行中的项目
// 获取当前项目进度
func (c *Project) GetInProgressProjectList(TenantId uint64) (projectList []ProjectIpData, err error) {

	// 获取进行中状态ids
	var StatusService Status
	corresponds := []string{"in_progress", "daily", "feedback"}
	ipStatusIds, ipStatusMap := StatusService.GetStatusIdsByCorrespond(corresponds)

	// 获取项目列表
	projectDb := ClickHouse.DB.Model(&model.Project{})
	projectDb.Where("simpleJSONExtractString(`project`.`json`, 'project_status') IN ?", ipStatusIds)
	// 指定租户
	projectDb.Where("tenant_id = ?", TenantId)
	// 排除demo项目
	projectDb.Where("is_demo = ?", "no")
	err = projectDb.Select("project.*,simpleJSONExtractString(`project`.`json`, 'project_status') as project_status").Find(&projectList).Error
	if err != nil {
		return
	}

	// 判断获取当前项目完成情况统计

	// 回插数据
	for index, projectItem := range projectList {
		projectList[index].Status = ipStatusMap[projectItem.ProjectStatus]
		projectList[index].Percent, err = getProjectTaskPercent(projectItem.Id)
		if err != nil {
			return
		}
	}

	return
}

// GetAllSpendReq 获得租户项目总花费
func (c *Project) GetAllSpendReq(tenantId uint64) (res GetAllSpendReq, err error) {
	var timeCostSecond uint64
	err = ClickHouse.DB.Model(&model.TimeLog{}).Where("tenant_id = ?", tenantId).
		Where("complete = 'yes'").
		Pluck("sum(end_time-start_time) as cost", &timeCostSecond).Error
	if err != nil {
		return
	}
	res.Date = timeCostSecond / 3600
	err = ClickHouse.DB.Model(&model.TimeLog{}).Where("tenant_id = ?", tenantId).Pluck("COUNT(DISTINCT created_by) as user", &res.User).Error
	return
}

// GetProjectNameMapByIds 通过项目id查询项目名称映射字典
func (c *Project) GetProjectNameMapByIds(projectIds []uint64) (projectNameMapRes map[uint64]string, err error) {
	var projectList []ProjectNameMapData

	// 获取项目列表
	projectDb := ClickHouse.DB.Model(&model.Project{})
	projectDb.Where("id IN ?", projectIds)
	err = projectDb.Find(&projectList).Error

	if err != nil {
		return
	}

	var projectNameMap = make(map[uint64]string, 0)
	for _, projectItem := range projectList {
		projectNameMap[uint64(projectItem.Id)] = projectItem.Name
	}
	return projectNameMap, err
}

// GetUserProjectByIds 通过用户id获取所在的项目id
func (c *Project) GetUserProjectByIds(imUserId int64, tenantId int64) (projectIds []int64, err error) {

	var status []model.Status
	err = ClickHouse.DB.Model(&model.Status{}).
		Where("correspond in ('in_progress', 'daily', 'feedback')").Find(&status).Error
	if err != nil {
		return
	}
	var statusId []string
	for _, v := range status {
		statusId = append(statusId, strconv.Itoa(int(v.Id)))
	}

	userId, err := GetSaasUserIdByUnionId(imUserId)
	if err != nil {
		return
	}

	var projectId []uint64
	err = ClickHouse.DB.Model(&model.ProjectMember{}).
		Where("user_id = ?", userId).
		Group("`project_member`.project_id").
		Pluck("project_id", &projectId).Error
	if err != nil {
		return
	}
	if len(projectId) > 0 {
		err = ClickHouse.DB.Model(&model.Project{}).
			Where("tenant_id = ?", tenantId).
			Where("id IN (?)", projectId).
			Where("JSONExtract(project.json, 'project_status', 'String') IN (?)", statusId).
			Pluck("id", &projectIds).Error
	}
	return
}

//通过im 的 user id 获取项目id
func GetImUserProjectIdListByRoleCode(userId int64, tenantId int64, roleCodeList []string, projectCorrespond []string) (res []uint64, err error) {
	saasUserId, errOccurred := GetSaasUserIdByUnionId(userId)
	if errOccurred != nil {
		err = errOccurred
		resInt := make([]uint64, 0)
		res = resInt
		return res, err
	}
	res, err = GetUserProjectIdListByRoleCode(saasUserId, tenantId, roleCodeList, projectCorrespond)
	return
}

func GetUserProjectIdListByRoleCode(userId int64, tenantId int64, roleCodeList []string, projectCorrespond []string) (res []uint64, err error) {
	db := ClickHouse.DB.Model(&model.ProjectMember{}).Joins("JOIN project p on p.id = project_member.project_id").
		Where("project_member.user_id = ?", userId)
	if len(roleCodeList) > 0 {
		db = db.Where("project_member.role_code in ?", roleCodeList)
	}

	if tenantId != 0 {
		db = db.Where("project.tenant_id = ?", tenantId)
	}

	if len(projectCorrespond) > 0 {
		var statusIdList []uint
		err = ClickHouse.DB.Model(&model.Status{}).Where("correspond in ?", projectCorrespond).Pluck("id", &statusIdList).Error
		if err != nil || len(statusIdList) == 0 {
			return
		}
		db = db.Where("simpleJSONExtractInt(project.json,'project_status') in ?", statusIdList)
	}
	err = db.Select("project_member.project_id").Group("project_member.project_id").Pluck("project_member.project_id", &res).Error
	return
}

// GetList 获取项目列表
func (c *Project) GetList(where interface{}) (res []model.Project, err error) {
	err = ClickHouse.DB.Model(&model.Project{}).Where(where).Find(&res).Error
	return
}

// ProjectListV2 获取进行中的项目列表
// correspond = in_progress，daily，feedback 这三种类型的状态为进行中的项目
func (c *Project) ProjectListV2(ctx *gin.Context, TenantId int64) (res []types.ProjectListV2Item, err error) {

	var optionService = Option{}
	projectIdList, err := optionService.GetBiConfigShowProjectIdList(ctx)
	if err != nil || len(projectIdList) == 0 {
		return
	}

	// 获取项目列表
	projectDb := ClickHouse.DB.Model(&model.Project{}).Where("id in (?)", projectIdList)

	var projectList []model.Project
	err = projectDb.
		Select("project.*").
		Order("project.id ASC").
		Find(&projectList).
		Error
	if err != nil {
		return
	}

	existProjectIdList := make([]uint64, 0)
	for _, item := range projectList {
		existProjectIdList = append(existProjectIdList, item.Id)
	}

	// 查询播出情况
	var playedProjectIdList []uint64
	err = ClickHouse.DB.Model(&model.Entity{}).
		Where("project_id in (?) and module_id = (select id from module where code = ?)", existProjectIdList, "episode").
		Where("simpleJSONExtractInt(json,'episode_plan_show_time') <= toUnixTimestamp(now()) and simpleJSONExtractInt(json,'episode_plan_show_time') > 0").
		Group("project_id").
		Pluck("project_id", &playedProjectIdList).Error
	if err != nil {
		return
	}

	// 查询播出情况
	var makingProjectIdList []uint64
	err = ClickHouse.DB.Model(&model.Entity{}).
		Where("project_id in (?) and module_id = (select id from module where code = ?)", existProjectIdList, "episode").
		Where("simpleJSONExtractUInt(json,'episode_status') = 4").
		Group("project_id").
		Pluck("project_id", &makingProjectIdList).Error
	if err != nil {
		return
	}
	makingProjectIdMap := make(map[uint64]bool, len(makingProjectIdList))
	playedProjectIdMap := make(map[uint64]bool, len(playedProjectIdList))
	for _, i2 := range playedProjectIdList {
		playedProjectIdMap[i2] = true
	}
	for _, i2 := range makingProjectIdList {
		makingProjectIdMap[i2] = true
	}
	res = make([]types.ProjectListV2Item, len(projectList))

	biProjectConfigMap, err := optionService.SelectBiProjectConfig(ctx, existProjectIdList)
	if err != nil {
		return
	}
	var statusText = ""
	var t types.ProjectListV2Item
	for i, project := range projectList {
		statusText = ""
		if _, ok := playedProjectIdMap[project.Id]; ok {
			if project.DramaType == "year" {
				statusText = "serializing"
			} else {
				statusText = "playing"
			}
		} else {
			if _, ok := makingProjectIdMap[project.Id]; ok {
				statusText = "making"
			} else {
				statusText = "creative"
			}
		}

		t = types.ProjectListV2Item{
			Id:         project.Id,
			Name:       project.Name,
			StatusText: statusText,
		}
		if _, ok := biProjectConfigMap[int64(project.Id)]; ok {
			t.PreviewImageBig = biProjectConfigMap[int64(project.Id)].ProjectPreviewImg.Big
			t.PreviewImageMiddle = biProjectConfigMap[int64(project.Id)].ProjectPreviewImg.Middle
			t.PreviewImageSmall = biProjectConfigMap[int64(project.Id)].ProjectPreviewImg.Small
		}
		res[i] = t
	}

	return
}

// ProjectManResourceDistribution  项目人力资源分布情况
func (c *Project) ProjectManResourceDistribution(ctx *gin.Context, projectId uint64) (res types.ProjectManResourceDistributionRes, err error) {

	var currentProject model.Project
	var allProjectIdList []int64
	err = ClickHouse.DB.Model(&model.Project{}).Where("id = ?", projectId).Find(&currentProject).Error
	if err != nil || currentProject.Id <= 0 {
		return
	}
	allProjectIdList = append(allProjectIdList, int64(currentProject.Id))

	var belongProjectList []model.Project
	err = ClickHouse.DB.Model(&model.Project{}).Where("belong_project_id = ?", projectId).Find(&belongProjectList).Error
	if err != nil {
		return
	}
	var allTenantIdList = make([]int64, len(belongProjectList)+1)
	var belongProjectTenantMap = make(map[int64]int64)
	belongProjectTenantMap[int64(currentProject.Id)] = int64(currentProject.TenantId)
	for i, project := range belongProjectList {
		allTenantIdList[i] = int64(project.TenantId)
		belongProjectTenantMap[int64(project.Id)] = int64(project.TenantId)
		allProjectIdList = append(allProjectIdList, int64(project.Id))
	}

	allTenantIdList = append(allTenantIdList, int64(currentProject.TenantId))
	var tenantGroupService TenantGroup
	groupMemberByProject, err := tenantGroupService.GetTenantGroupMemberByProject(ctx, int64(currentProject.TenantId), allTenantIdList, "yes", "yes")
	if err != nil {
		return
	}

	// 查询项目成员统计
	var projectMemberCountList []types.ProjectMemberCountList
	err = ClickHouse.DB.Model(&model.ProjectMember{}).Where("project_id in ?", allProjectIdList).
		Select("count(distinct user_id) AS count,project_id").Group("project_id").Find(&projectMemberCountList).Error
	if err != nil {
		return
	}
	var tenantProjectMemberCountMap = make(map[int64]int64, 0)
	for _, list := range projectMemberCountList {
		// 映射到对应的租户和人数
		if _, ok := belongProjectTenantMap[list.ProjectId]; ok {
			tenantProjectMemberCountMap[belongProjectTenantMap[list.ProjectId]] = list.Count
		}
	}

	var groupMemberIdMap = make(map[int64]bool)
	for _, id := range groupMemberByProject.Data.TenantGroupMemberIds {
		groupMemberIdMap[id] = true
	}
	var tempMemberCount int64 = 0

	for tempTenantId, tempTenantAddressInfo := range groupMemberByProject.Data.TenantAddress {
		tempTenantIdFormatted, _ := strconv.ParseInt(tempTenantId, 10, 64)
		if tempTenantIdFormatted <= 0 {
			continue
		}
		// 公司参与项目人数
		if _, ok := tenantProjectMemberCountMap[tempTenantIdFormatted]; ok {
			tempMemberCount = tenantProjectMemberCountMap[tempTenantIdFormatted]
		} else {
			tempMemberCount = 0
		}
		// 公司坐标
		tempCoordinate := strings.Split(tempTenantAddressInfo.CityCoordinate, ",")
		var tempAddressInfo = types.SupplierAddressManNumberDataItem{
			ProjectMemberNumber: tempMemberCount,
			TenantName:          tempTenantAddressInfo.CompanyName,
			TenantAddress:       tempTenantAddressInfo.CompanyOfficeAddress,
			Province:            tempTenantAddressInfo.Province,
			Cities:              tempTenantAddressInfo.Cities,
		}
		if len(tempCoordinate) >= 2 {
			tempAddressInfo.Longitude = tempCoordinate[0]
			tempAddressInfo.Latitude = tempCoordinate[1]
		}

		if _, ok := groupMemberIdMap[tempTenantIdFormatted]; ok {
			// 是集团内部公司
			res.InsideManNumber += tempMemberCount
			tempAddressInfo.Type = "inside"
		} else {
			res.OutsideManNumber += tempMemberCount
			tempAddressInfo.Type = "outside"
		}
		if uint64(tempTenantIdFormatted) == currentProject.TenantId {
			res.SupplierAddressManNumberData = append([]types.SupplierAddressManNumberDataItem{tempAddressInfo}, res.SupplierAddressManNumberData...)
		} else {
			res.SupplierAddressManNumberData = append(res.SupplierAddressManNumberData, tempAddressInfo)
		}
	}

	return
}

// ProjectEpisodeList 项目正常规划项目剧集信息
func (c *Project) ProjectEpisodeList(projectId int64) (res []model.Entity, err error) {
	// 剧集信息汇总
	err = ClickHouse.DB.Model(&model.Entity{}).Where("module_id = (select id from module where code = 'episode')").
		Where("project_id = ? and name like 'EP%' and length(name) = 5", projectId).
		Select("id,name,code,simpleJSONExtractString(json,'episode_is_seal') as episode_is_seal,simpleJSONExtractString(json,'episode_is_show') as episode_is_show").
		Find(&res).Error
	if err != nil {
		return
	}
	return
}

// ProjectDetail 项目详情
func (c *Project) ProjectDetail(ctx *gin.Context, projectId uint64) (res types.ProjectDetailRes, err error) {
	// 项目基本信息查询
	var project model.Project
	err = ClickHouse.DB.Model(&model.Project{}).Where("id = ?", projectId).Find(&project).Error
	if err != nil || project.Id == 0 {
		return
	}
	res.ProjectId = int64(project.Id)
	res.ProjectName = project.Name
	var optionService Option
	// 查询投入/花费配置
	projectBiConfig, err := optionService.GetProjectBiConfig(ctx, projectId)
	if err != nil {
		return
	}

	res.Invested = projectBiConfig.Invested.Value
	res.Spent = projectBiConfig.Spent.Value
	res.InvestedUnit = projectBiConfig.Invested.Unit
	res.SpentUnit = projectBiConfig.Spent.Unit
	res.PreviewMakingVideoList = projectBiConfig.DetailVideoList

	// 查询已完成剧集
	var TotalEpisodeCodeList []string

	// 剧集信息汇总
	episodeList, err := c.ProjectEpisodeList(int64(projectId))
	if err != nil {
		return
	}
	var totalEpisodeIdList []int64
	var doneEpisodeIdList []int64
	for _, episode := range episodeList {
		TotalEpisodeCodeList = append(TotalEpisodeCodeList, episode.Code)
		res.PlanEpisodeNumber += 1
		if episode.EpisodeIsShow == "yes" {
			res.OnlineEpisodeNumber += 1
		}
		if episode.EpisodeIsSeal == "yes" {
			res.DoneEpisodeNumber += 1
			doneEpisodeIdList = append(doneEpisodeIdList, int64(episode.Id))
		}
		totalEpisodeIdList = append(totalEpisodeIdList, int64(episode.Id))
	}
	if projectBiConfig.EpisodeStatusCount.Done > 0 {
		res.DoneEpisodeNumber = projectBiConfig.EpisodeStatusCount.Done
	}
	if projectBiConfig.EpisodeStatusCount.Online > 0 {
		res.OnlineEpisodeNumber = projectBiConfig.EpisodeStatusCount.Online
	}
	if projectBiConfig.EpisodeStatusCount.Plan > 0 {
		res.PlanEpisodeNumber = projectBiConfig.EpisodeStatusCount.Plan
	}

	if projectBiConfig.TaskStatusCount.Total > 0 {
		res.TaskTotalNumber = projectBiConfig.TaskStatusCount.Total
	} else {
		// 总任务数
		err = ClickHouse.DB.Model(&model.Task{}).
			Joins("JOIN entity on entity.id = task.entity_id").
			Where("task.entity_module_id IN (select id from module where code in ?)", []string{"asset", "level", "design", "shot", "sequence"}).
			Where("entity.initial_episode_code IN ?", TotalEpisodeCodeList).
			Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
			Where("task.project_id = ? and task.step_type = 'step'", projectId).Select("count(task.id) as count").
			Pluck("count", &res.TaskTotalNumber).Error
		if err != nil {
			return
		}
	}
	if projectBiConfig.TaskStatusCount.Done > 0 {
		res.TaskDoneNumber = projectBiConfig.TaskStatusCount.Done
	} else {
		// 已完成任务数
		err = ClickHouse.DB.Model(&model.Task{}).
			Joins("JOIN entity on entity.id = task.entity_id").
			Where("entity.initial_episode_code IN ?", TotalEpisodeCodeList).
			Where("task.entity_module_id IN (select id from module where code in ?)", []string{"asset", "level", "design", "shot", "sequence"}).
			Where("simpleJSONExtractInt(task.json,'task_status') = (select id from status where code = 'final' limit 1)").
			Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
			Where("task.project_id = ? and task.step_type = 'step'", projectId).Select("count(task.id) as count").
			Pluck("count", &res.TaskDoneNumber).Error
		if err != nil {
			return
		}
	}

	// 项目最近的播出时间
	err = ClickHouse.DB.Model(&model.Entity{}).Where("module_id = (select id from module where code = 'episode')").
		Where("project_id = ? and name like 'EP%' and length(name) = 5 and simpleJSONExtractInt(json, 'episode_plan_show_time') > 0", projectId).
		Pluck("min(simpleJSONExtractInt(json, 'episode_plan_show_time'))", &res.FirstPlanPlayTime).Error
	return
}

func (c *Project) ProjectTaskSubmitCountByDate(projectId uint64, dateStringStart string, dateStringEnd string) (res []types.ProjectTaskSubmitCountByDateResItem, err error) {

	resDateStr := GetBetweenDates(dateStringStart, dateStringEnd)
	resMap := make(map[string]*types.ProjectTaskSubmitCountByDateResItem, len(resDateStr))
	res = make([]types.ProjectTaskSubmitCountByDateResItem, len(resDateStr))
	for i, s := range resDateStr {
		res[i] = types.ProjectTaskSubmitCountByDateResItem{
			Date:               s,
			VersionPassCount:   0,
			VersionSubmitCount: 0,
		}
		resMap[s] = &res[i]
	}

	var countPassByDate []types.VersionPassSubmitCountByDate
	dateStart, err := time.ParseInLocation("2006-01-02", dateStringStart, time.Local)
	if err != nil {
		return
	}
	dateEnd, err := time.ParseInLocation("2006-01-02", dateStringEnd, time.Local)
	if err != nil {
		return
	}

	// 提交次数查询
	err = ClickHouse.DB.Model(&model.Version{}).
		Where("project_id = ? and created >= ? and created <= ?", projectId, dateStart.Unix(), dateEnd.AddDate(0, 0, 1).Add(-1).Unix()).
		Select("count(id) as count,formatDateTime(toDate(created), '%Y-%m-%d') as date,is_pass").
		Group("formatDateTime(toDate(created),'%Y-%m-%d') , is_pass").
		Find(&countPassByDate).Error
	if err != nil {
		return
	}
	for _, date := range countPassByDate {
		resMap[date.Date].VersionSubmitCount += date.Count
		if date.IsPass == "yes" {
			resMap[date.Date].VersionPassCount += date.Count
		}
	}

	return
}

// ProjectTaskDoneGroupedCount 项目任务完成数量分组统计
func (c *Project) ProjectTaskDoneGroupedCount(ctx *gin.Context, projectId uint64) (res types.ProjectTaskDoneGroupedCountRes, err error) {
	var optionService Option
	// 查询投入/花费配置
	projectBiConfig, err := optionService.GetProjectBiConfig(ctx, projectId)
	// 查询已完成剧集
	var doneEpisodeCodeList, TotalEpisodeCodeList, undoneEpisodeCodeList []string
	projectEpisodeList, err := c.ProjectEpisodeList(int64(projectId))
	if err != nil {
		return
	}
	for _, episode := range projectEpisodeList {
		TotalEpisodeCodeList = append(TotalEpisodeCodeList, episode.Code)
		if episode.EpisodeIsSeal == "yes" {
			doneEpisodeCodeList = append(doneEpisodeCodeList, episode.Code)
		} else {
			undoneEpisodeCodeList = append(undoneEpisodeCodeList, episode.Code)
		}
	}

	// 全部任务数
	if projectBiConfig.TaskStatusCount.Total > 0 {
		res.Total = projectBiConfig.TaskStatusCount.Total
	} else {
		err = ClickHouse.DB.Model(&model.Task{}).Joins("JOIN entity on entity.id = task.entity_id").
			Where("task.project_id = ? and task.step_type = 'step' and entity.module_id in (select id from module where code in ('design', 'asset', 'level', 'shot', 'sequence') )", projectId).
			Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
			Where("entity.initial_episode_code in ?", TotalEpisodeCodeList).
			Count(&res.Total).Error
		if err != nil {
			return
		}
	}

	// 已完成的任务数量
	if projectBiConfig.TaskStatusCount.Done > 0 {
		res.Done = projectBiConfig.TaskStatusCount.Done
	} else {
		err = ClickHouse.DB.Model(&model.Task{}).Joins("JOIN entity on entity.id = task.entity_id").
			Where("task.project_id = ? and task.step_type = 'step' and entity.module_id in (select id from module where code in ('design', 'asset', 'level', 'shot', 'sequence') )", projectId).
			Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
			Where("simpleJSONExtractInt(task.json, 'task_status') in (select id from status where code = 'final')").
			Where("entity.initial_episode_code in ?", TotalEpisodeCodeList).
			Count(&res.Done).Error
		if err != nil {
			return
		}
	}

	inprogressStatusCode := []string{"remake", "inprogress", "submitted", "feedback", "ready_to_publish", "wait_for_party_a_review", "wait_partyb_submit"}

	// 进行中
	if projectBiConfig.TaskStatusCount.Inprogress > 0 {
		res.InProgress = projectBiConfig.TaskStatusCount.Inprogress
	} else {
		if len(undoneEpisodeCodeList) > 0 {
			// 查询进行中
			err = ClickHouse.DB.Model(&model.Task{}).
				Joins("JOIN entity on entity.id = task.entity_id").
				Where("task.project_id = ? and task.step_type = 'step' and entity.module_id in (select id from module where code in ('design', 'asset', 'level', 'shot', 'sequence') )", projectId).
				Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
				Where("entity.initial_episode_code in ?", undoneEpisodeCodeList).
				Where("simpleJSONExtractInt(task.json, 'task_status') in (select id from status where code in ?)", inprogressStatusCode).
				Count(&res.InProgress).Error
			if err != nil {
				return
			}
		}
	}
	// 逾期
	if projectBiConfig.TaskStatusCount.Overdue > 0 {
		res.CurrentOverdue = projectBiConfig.TaskStatusCount.Overdue
	} else {
		if len(undoneEpisodeCodeList) > 0 {
			// 查询逾期任务数据
			err = ClickHouse.DB.Model(&model.Task{}).
				Joins("JOIN entity on entity.id = task.entity_id").
				Where("task.project_id = ? and task.step_type = 'step' and entity.module_id in (select id from module where code in ('design', 'asset', 'level', 'shot', 'sequence') )", projectId).
				Where("JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and simpleJSONExtractInt(task.json,'task_status') <> 3").
				Where("entity.initial_episode_code in ?", undoneEpisodeCodeList).
				Where("simpleJSONExtractInt(task.json, 'task_status') in (select id from status where code in ?)", inprogressStatusCode).
				Where("simpleJSONExtractString(task.json, 'task_is_overdue') = 'yes'").
				Count(&res.CurrentOverdue).Error
			if err != nil {
				return
			}
		}
	}

	return

}

// ProjectStepCategoryDoneCount 项目环节产出情况
func (c *Project) ProjectStepCategoryDoneCount(projectId uint64) (res []types.ProjectStepCategoryDoneCountResItem, err error) {
	var countModuleCodeList = []string{"design", "level", "asset", "shot"}
	var doneCountRes []types.StepCategoryCount
	err = ClickHouse.DB.Model(&model.Task{}).
		Where("project_id = ? and entity_module_id in (select id from module where code in ?)", projectId, countModuleCodeList).
		Where("step_type = 'step_category' and simpleJSONExtractInt(json, 'task_status') = (select id from status where code = 'final')").
		Where("JSONLength(JSONExtractString(json, 'task_deprecate_data')) = 0").
		Group("step_category_id").
		Select("step_category_id,count(id) as Number").
		Find(&doneCountRes).
		Error
	if err != nil || len(doneCountRes) == 0 {
		return
	}

	var stepCategoryIdList = make([]int64, len(doneCountRes))
	doneCountResMap := make(map[int64]*types.StepCategoryCount, len(doneCountRes))
	for i, re := range doneCountRes {
		stepCategoryIdList[i] = re.StepCategoryId
		doneCountResMap[re.StepCategoryId] = &doneCountRes[i]
	}

	err = ClickHouse.DB.Model(&model.StepCategory{}).Where("id in ?", stepCategoryIdList).Select("id,name").Order("index ASC").Find(&res).Error
	for i, re := range res {
		res[i].Number = doneCountResMap[re.Id].Number
	}
	return
}

// ProjectAssetPreviewCheck 资产巡检
func (c *Project) ProjectAssetPreviewCheck(ctx *gin.Context, projectId uint64) (res types.ProjectAssetPreviewCheckRes, err error) {

	countModuleCode := []string{"design", "asset", "level"}
	err = ClickHouse.DB.Model(&model.Task{}).Joins("JOIN entity on entity.id = task.entity_id join module on module.id = entity.module_id").
		Select("multiIf(module.code = 'design', simpleJSONExtractString(entity.json, 'design_category'), module.code = 'asset', simpleJSONExtractString(entity.json, 'asset_category'), module.code = 'level',simpleJSONExtractString(entity.json, 'level_category'), '') as name,count(task.id) as number").
		Where("task.project_id = ? and task.entity_module_id in (select id from module where code in ?) and simpleJSONExtractInt(task.json, 'task_status') = (select id from status where code = ?)", projectId, countModuleCode, "final").
		Group("name").Find(&res.AssetCategoryDoneTaskCount).Error
	if err != nil {
		return
	}
	var optionService Option
	BiProjectConfig, err := optionService.GetProjectBiConfig(ctx, projectId)
	if err != nil {
		return
	}
	res.PreviewMakingVideoList = BiProjectConfig.AssetVideoList
	return
}

// ProjectInprogressEpisode 项目进行中剧集
func (c *Project) ProjectInprogressEpisode(ctx *gin.Context, projectId uint64) (res []types.ProjectInprogressEpisodeResItem, err error) {

	var inprogressEpisodeList []model.Entity
	var optionService Option
	// 查询投入/花费配置
	projectBiConfig, err := optionService.GetProjectBiConfig(ctx, projectId)
	if len(projectBiConfig.InprogressEpisode) > 0 {
		err = ClickHouse.DB.Model(&model.Entity{}).Where("project_id = ?", projectId).
			Where("module_id = (select id from module where code = 'episode')").
			Where("entity.id in (?)", projectBiConfig.InprogressEpisode).
			Find(&inprogressEpisodeList).Error
	} else {
		err = ClickHouse.DB.Model(&model.Entity{}).Where("project_id = ?", projectId).
			Where("module_id = (select id from module where code = 'episode')").
			Where("simpleJSONExtractInt(json, 'episode_status') = (select id from status where code = 'inprogress' limit 1) and (simpleJSONExtractString(json, 'episode_is_seal') = '' or simpleJSONExtractString(json, 'episode_is_seal') = 'no')").
			Find(&inprogressEpisodeList).Error
	}
	if err != nil || len(inprogressEpisodeList) == 0 {
		return
	}
	var episodeIdList = make([]uint64, len(inprogressEpisodeList))
	var inprogressEpisodeMap = make(map[int64]*model.Entity, len(inprogressEpisodeList))
	for i, entity := range inprogressEpisodeList {
		episodeIdList[i] = entity.Id
		inprogressEpisodeMap[int64(entity.Id)] = &inprogressEpisodeList[i]
	}

	err = ClickHouse.DB.Model(&model.Task{}).Joins("JOIN (select distinct episode_id, entity_id from entity_episode_relation where project_id = ? and episode_id in ?) epr on task.entity_id = epr.entity_id", projectId, episodeIdList).
		Select("epr.episode_id as episode_id,count(task.id) as total_task_number,count(if(simpleJSONExtractInt(task.json, 'task_status') = 7, 1, null)) as undone_task_number").
		Group("epr.episode_id").
		Find(&res).
		Error
	if err != nil {
		return
	}
	for i, resItem := range res {
		if _, ok := inprogressEpisodeMap[resItem.EpisodeId]; !ok {
			continue
		}
		res[i].EpisodeName = inprogressEpisodeMap[resItem.EpisodeId].Name
	}

	return
}
